package service

import (
	"batbat-backend/app/dao"
	"batbat-backend/app/model"
	"context"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gtime"
)

// GameFavor 游戏收藏服务
var GameFavor = gameFavorService{}

type gameFavorService struct{}

// FavorGame 用户收藏一个游戏
func (gfs *gameFavorService) FavorGame(ctx context.Context, uid uint, gid uint) error {
	return g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		// 查看用户是否已经收藏过游戏
		count, err := dao.GameFavor.Ctx(ctx).TX(tx).
			Where(dao.GameFavor.Columns.Uid, uid).
			Where(dao.GameFavor.Columns.Gid, gid).
			WhereNull(dao.GameFavor.Columns.DeleteTime).
			Count()
		if err != nil {
			g.Log().Ctx(ctx).Errorf("查询数据库发生错误: %v", err)
			return gerror.New("收藏失败")
		}
		if count > 0 {
			return gerror.New("已收藏过该游戏, 无法再次收藏")
		}
		// 收藏游戏, 使用save在重复unique index的时候更新, 节约空间
		_, err = dao.GameFavor.Ctx(ctx).TX(tx).FieldsEx(dao.GameFavor.Columns.Id).Save(&model.GameFavor{
			Gid:        gid,
			Uid:        uid,
			CreateTime: gtime.Now(),
			DeleteTime: nil,
		})
		if err != nil {
			g.Log().Ctx(ctx).Errorf("插入数据库发生错误: %v", err)
			return gerror.New("收藏失败")
		}
		return nil
	})
}

// UnFavorGame 用户取消收藏游戏
func (gfs *gameFavorService) UnFavorGame(ctx context.Context, uid uint, gid uint) error {
	return g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		// 查看用户是否已经收藏过游戏
		var favor *model.GameFavor
		err := dao.GameFavor.Ctx(ctx).TX(tx).
			Fields(dao.GameFavor.Columns.Id).
			Where(dao.GameFavor.Columns.Uid, uid).
			Where(dao.GameFavor.Columns.Gid, gid).
			WhereNull(dao.GameFavor.Columns.DeleteTime).
			Scan(&favor)
		if err != nil {
			g.Log().Ctx(ctx).Errorf("查询数据库失败: %v", err)
			return gerror.New("取消收藏失败")
		}
		if favor == nil || favor.Id == 0 {
			return gerror.New("暂未收藏该游戏")
		}
		// 取消收藏
		data := g.MapStrAny{dao.GameFavor.Columns.DeleteTime: gtime.Now()}
		_, err = dao.GameFavor.Ctx(ctx).TX(tx).WherePri(favor.Id).Update(data)
		if err != nil {
			g.Log().Ctx(ctx).Errorf("修改数据库失败: %v", err)
			return gerror.New("取消收藏失败")
		}
		return nil
	})
}